/*
 *   Copyright (C) 2009 Ultratronik Entwicklungs GmbH 
 *
 *     - Author: Sören Wellhöfer <soeren.wellhoefer@gmx.net>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 */

#ifndef MAEPLAY_HPP
#define MAEPLAY_HPP

#include <vector>

#include <QWidget>
#include <QPushButton>
#include <QDesktopWidget>
#include <QRect>
#include <QIcon>
#include <QString>
#include <QApplication>
#include <QPixmap>
#include <QTimer>
#include <QMessageBox>

#include "aux.hpp"


class PlayerButton : public QPushButton
{

public:
	static const float rel_height = 0.75;
	static const float rel_width = 0.25;
	static const float rel_icon = 0.8;
	static const int btn_interspace = 50;
	
	PlayerButton(QWidget *p, QString path) : QPushButton(p)
	{
		this->setIcon(QIcon(path));
	}
};

typedef std::vector<PlayerButton*> BtnVec;

class PlayerUI : public QWidget
{
	Q_OBJECT
	
private:
	BtnVec btns;
	enum {
		PLAY_BUTTON = 0,
		PAUSE_BUTTON,
		STOP_BUTTON
	};
	
	Player player;
	QTimer update_pulse;
public:

	static const float rel_height = 0.05;
	
	PlayerUI() : QWidget(NULL, Qt::Window | Qt::WindowStaysOnTopHint |
			     Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint),
		     update_pulse(this)
	{
		// Set window
		QDesktopWidget *dsk = QApplication::desktop();
		const QRect screen = dsk->screenGeometry();
		int w = screen.width(), h = screen.height();
		int height = (int)(h * rel_height);

		this->resize(w, height);
		this->move(0, h - height);
		this->setStyleSheet("background-color: orange");

		// Add buttons
		btns.push_back(new PlayerButton(this, "play.png"));
		connect(btns.back(), SIGNAL(clicked()), this, SLOT(play()));

		btns.push_back(new PlayerButton(this, "pause.png"));
		connect(btns.back(), SIGNAL(clicked()), this, SLOT(pause()));

		btns.push_back(new PlayerButton(this, "stop.png"));
		connect(btns.back(), SIGNAL(clicked()), this, SLOT(stop()));

		set_btn_states(true, false, false);

		// Place buttons
		int btn_w = (int)(w * PlayerButton::rel_width);
		int btn_h = (int)(height * PlayerButton::rel_height);
		int mwidth = (int)(btns.size() * (btn_w + PlayerButton::btn_interspace));
		int posx = (int)(0.5 * (w - mwidth));
		int posy = (int)(0.5 * (height - btn_h));
		
		for (BtnVec::const_iterator it = btns.begin(); it != btns.end(); it++) {

			PlayerButton *b = *it;
			b->resize(btn_w, btn_h);
			b->move(posx, posy);
			
			b->setIcon(QIcon(b->icon().pixmap((int)(PlayerButton::rel_icon * btn_w),
							  (int)(PlayerButton::rel_icon * btn_h))));
			
			posx += btn_w + PlayerButton::btn_interspace;
		}
		
		// Launch player
		player.launch(w, h - 2*height); //FIXME
		connect(&update_pulse, SIGNAL(timeout()), this, SLOT(update_player_status()));
		update_pulse.start(500);

		// Debugging timer; if you're too lazy or your panel doesn't work ...
		QTimer *debug_t = new QTimer();
		connect(debug_t, SIGNAL(timeout()), this, SLOT(debug()));
		//debug_t->start(10000);
	}


	~PlayerUI()
	{
		for (BtnVec::const_iterator it = btns.begin(); it != btns.end(); it++)
			delete *it;
	}

	void open(Player::Codec codec, std::string path)
	{
		player.open(codec, path);
	}

private:

	void set_btn_states(bool pl, bool pa, bool st)
	{
		btns.at(PLAY_BUTTON)->setEnabled(pl);
		btns.at(PAUSE_BUTTON)->setEnabled(pa);
		btns.at(STOP_BUTTON)->setEnabled(st);
	}

public slots:

	void play()
	{		
		player.play();
		set_btn_states(false, true, true);
	}

	void pause()
	{
		player.pause();
		set_btn_states(true, false, true);
	}
	
	void stop()
	{
		player.stop();
		set_btn_states(true, false, false);
		
	}

private slots:

	void update_player_status()
	{
		player.update_status();
		if(player.get_state() == Player::ERROR) {
			QMessageBox::critical(this, QString("MAEplayer Error"),
					     QString("MAIplayer reports:\n") +
					     QString(player.last_err().c_str()),
					     QMessageBox::Ok);

			exit(1);
		}
	}

	// See QTimer debug_t in ctor
	// Simulates a number of button presses
	void debug()
	{
		static int seq;

		switch(++seq) {
			case 1: play(); break;
			case 2: pause(); break;
			case 3: stop(); break;
			case 4: play(); break;
		}
	}

};

#endif
